#include <QLabel>
#include <QMouseEvent>
#include "FloatButton.h"
#include "platform/common.h"

#include <cassert>

FloatButton::FloatButton(QWidget *parent) : QWidget(parent)
{
    setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
    // setAttribute(Qt::WA_TranslucentBackground);
    connect(ConfigData::instance().translate->enabledAPIs, &ConfigItem::itemEdited, this, &FloatButton::onConfigChanged);
    connect(ConfigData::instance().translate->primaryAPI, &ConfigItem::itemEdited, this, &FloatButton::onConfigChanged);
    connect(ConfigData::instance().ui->floatButtonSize, &ConfigItem::itemEdited, this, &FloatButton::onConfigChanged);

    connect(&Platform::monitor(), &IMonitor::mouseBtnPressed, this, &FloatButton::onMouseButtonPressed);
    connect(&Platform::monitor(), &IMonitor::mouseBtnReleased, this, &FloatButton::onMouseButtonReleased);
    connect(&Platform::monitor(), &IMonitor::contentPicked, this, &FloatButton::onContentPicked);

    connect(&Platform::monitor(), &IMonitor::mouseWheel, this, &FloatButton::hide);
    connect(&Platform::monitor(), QOverload<int>::of(&IMonitor::keyPressed), this, &FloatButton::hide);

    floatButtonMenu.addAction(&notShow);
    connect(&notShow, &QAction::triggered, this, &FloatButton::onNotShowActionTriggered);

    m_APIEnum = ConfigData::instance().translate->enabledAPIs->getMetaEnum();
    for (int i = 0; i < m_APIEnum.keyCount(); i++)
    {
        QLabel *iconLabel = new QLabel(this);
        iconLabel->setObjectName(m_APIEnum.valueToKey(m_APIEnum.value(i)));
        iconLabel->setScaledContents(true);
        QPixmap pic(":/resources/pictures/" + iconLabel->objectName() + ".png");
        iconLabel->setPixmap(pic);
        iconLabel->hide();
    }

    onConfigChanged();

}

void FloatButton::show()
{
    setFixedSize(m_length, m_length);
    QWidget::show();
}


void FloatButton::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        int index = event->x() / m_length;
        assert(0 <= index && index < m_shownAPIs.count());
        hide();
        emit floatButtonPressed(mousePressPosition, mouseReleasedPosition, Translate::API(m_shownAPIs[index]));
    }
    else if (event->button() == Qt::RightButton)
    {
        this->activateWindow();
        notShow.setText("不要在" + m_curAppName + "显示");
        floatButtonMenu.exec(QCursor::pos());
    }
}

void FloatButton::onConfigChanged()
{
    int primaryAPI = ConfigData::instance().translate->primaryAPI->get();
    QSet<int> enabledAPIs = ConfigData::instance().translate->enabledAPIs->get();

    if (primaryAPI == -1)
        primaryAPI = 0;

    m_length = ConfigData::instance().ui->floatButtonSize->get();

    m_shownAPIs.clear();
    m_shownAPIs.append(primaryAPI);
    QLabel *iconLabel = findChild<QLabel*>(m_APIEnum.valueToKey(primaryAPI));
    if (iconLabel)
    {
        iconLabel->move(0, 0);
        iconLabel->resize(m_length, m_length);
        iconLabel->show();
    }
    enabledAPIs.remove(primaryAPI);
    int index = 0;
    for (auto api : enabledAPIs)
    {
        m_shownAPIs.append(api);
        index++;
        iconLabel = findChild<QLabel*>(m_APIEnum.valueToKey(api));
        if (iconLabel)
        {
            iconLabel->move(index * m_length, 0);
            iconLabel->resize(m_length, m_length);
            iconLabel->show();
        }
    }

}


void FloatButton::onNotShowActionTriggered()
{
    ConfigData::PickMode pickMode = ConfigData::PickMode(ConfigData::instance().pickMode->get());
    if (pickMode == ConfigData::PickMode::All)
        ConfigData::instance().pickMode->set(ConfigData::PickMode::Custom);

    QStringList disabledApps = ConfigData::instance().disabledApps->get();
    if (!disabledApps.contains(m_curAppName))
        ConfigData::instance().disabledApps->appendString(m_curAppName);

    hide();

}

void FloatButton::enterEvent(QEvent *)
{
    setFixedWidth(ConfigData::instance().translate->enabledAPIs->get().count() * m_length);
}

void FloatButton::leaveEvent(QEvent *)
{
    setFixedWidth(m_length);
}

void FloatButton::onContentPicked(QString appName, QString content)
{
    Q_UNUSED(content)
    ConfigData::PickMode pickMode = ConfigData::PickMode(ConfigData::instance().pickMode->get());
    if (pickMode == ConfigData::PickMode::None)
    {
        return;
    }
    else if (pickMode == ConfigData::PickMode::Custom)
    {
        QStringList disabledApps = ConfigData::instance().disabledApps->get();
        if (disabledApps.contains(appName))
            return;
    }

    m_curAppName = appName;
    move(QCursor::pos() + QPoint(-10, 15));
    show();
}


void FloatButton::onMouseButtonPressed(QPoint p)
{
    if (p.x() < this->x() || p.x()  > this->x() + width() || p.y() < this->y() || p.y() > this->y() + height())
    {
        mousePressPosition = p;
    }
    if (this->isHidden() == false)
    {
        if (p.x()  < this->x() || p.x()  > this->x() + width() || p.y() < this->y() || p.y() > this->y() + height())
        {
            // 如果点击菜单，此处 hide()与triggered()有可能形成竞争，所以加一个判断。
            if (floatButtonMenu.isHidden())
                hide();
        }
        else
        {
            // go to mousePressEvent
        }
    }

}

void FloatButton::onMouseButtonReleased(QPoint p)
{
    if (p.x() < this->x() || p.x() > this->x() + width() || p.y() < this->y() || p.y() > this->y() + height())
    {
        mouseReleasedPosition = p;
    }
}
